#闭包
'''
两个函数的嵌套，内部函数使用到了外部函数的变量，这个现象就可以称之为产生闭包。
'''
#闭包的定义：
'''
闭包是函数内部定义的函数
1）闭包是嵌套在函数中的函数
2）闭包必须是内层函数对外层函数变量（非全局变量）的引用
'''
#构成条件
'''
1）函数中嵌套一个函数；
2）内层嵌套函数，对外部作用域有一个非全局变量的引用；
3）外层函数的返回值是内层函数的函数名；
'''
#例(闭包模板)
def outF():
    sum = n           #外层定义一个非全局变量
    def inF(n):
        return sum+1  #内层函数引用外层函数的非全局变量
    return inF        #外层函数返回值必须是内层函数的函数名
print('\n')

#闭包的作用：保存局部信息不被销毁，保证数据的安全性。
#闭包的应用：
'''
1）可以保存一些非全局变量但是不易被销毁，改变的数据
2）装饰器
3）实现数据锁定
'''

#函数嵌套
def outer():
    n = 10       #n为非全局变量
    def inner():
        n = 20   #n为内层函数的局部变量，与上面的n不是同一个变量,只是同名。
        print('inner函数',n)
    print('outer函数',n)
    inner()
outer()
print('\n')

#改成闭包形式
def outer(m):
    n = 10       #n为非全局变量
    def inner():
        print('inner函数',n+m)
    return inner
ot = outer(2)    #函数的调用
ot()
print('\n')

#修改闭包中外部函数中的变量  nonlocal
def outer(a):
    def inner():
        nonlocal a  #给外层函数变量声明,即使用的是外层函数的变量a，不声明就会自动创建一个内层变量a。
        a += 1
        print(a)
    return inner
ot = outer(1)
ot()
